package com.example.passwordmanager;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import android.Manifest;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Toast;

import com.example.passwordmanager.Util.DESUtil;
import com.example.passwordmanager.Util.QMUIDialogUtil;
import com.example.passwordmanager.Util.Sys;
import com.example.passwordmanager.Util.TimeUtil;
import com.example.passwordmanager.databinding.ActivitySetBinding;
import com.example.passwordmanager.db.AppDatabase;
import com.example.passwordmanager.db.UserBean;
import com.example.passwordmanager.db.UserDao;
import com.example.passwordmanager.dialog.EditTextDialogFragment;
import com.example.util.base_util.SPUtil;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.qmuiteam.qmui.widget.dialog.QMUIDialog;
import com.qmuiteam.qmui.widget.dialog.QMUIDialogAction;
import com.qmuiteam.qmui.widget.dialog.QMUITipDialog;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

public class SetActivity extends AppCompatActivity {

    ActivitySetBinding dataBinding;
    List<UserBean> list;
    private String json;

    boolean isIOUse = false;
    private String fileName = "密码管理.txt";
    private Executor executor = Executors.newSingleThreadExecutor();

    private static final int READ_REQUEST_CODE = 2;
    private String textContent;
    private QMUITipDialog tipDialog;

    private String readJson;

    private byte[] writeByte;

    private String key = "ohuangyyds";
    private final String key0 = "ohuangyyds";

    private EditTextDialogFragment outputDialog = new EditTextDialogFragment("设置一个密码", new EditTextDialogFragment.CallBack() {
        @Override
        public void onClick(String s) {
            if (Sys.canClick()) {
                if (!isIOUse) {
                    key = getKey(s);
                    isIOUse = true;
                    executor.execute(outputTask);
                } else {
                    Toast.makeText(SetActivity.this, "正在导出...", Toast.LENGTH_SHORT).show();
                }
            }
        }
    });
    private EditTextDialogFragment inputDialog = new EditTextDialogFragment("请输入密码", new EditTextDialogFragment.CallBack() {
        @Override
        public void onClick(String s) {
            readJson = readFile(getKey(s));

            if (TextUtils.isEmpty(readJson)) {
                Toast.makeText(SetActivity.this, "文件读取失败或密码错误", Toast.LENGTH_LONG).show();
            } else {
                executor.execute(insertTask);
            }
        }
    });

    private String getKey(String s) {
        if (TextUtils.isEmpty(s)) {
            return key0;
        }
        if (s.length() >= 8) {
            return s.substring(0, 8);
        } else {
            int l = s.length();
            return s.substring(0, l) + key0.substring(0, 8 - l);
        }

    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        dataBinding = ActivitySetBinding.inflate(getLayoutInflater());
        setContentView(dataBinding.getRoot());
        requestPower();
        String[] listItems = new String[]{
                "选择文件导入",
                "数据导出",
                "指纹开关设置",
                "导出为.html(不支持导入只能用于查看)",
                "数据导出路径:DownLoad/passwordManager",


        };

        List<String> data = new ArrayList<>();

        Collections.addAll(data, listItems);

        dataBinding.listview.setAdapter(new ArrayAdapter<>(this, R.layout.simple_list_item, data));
        dataBinding.listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                switch (position) {
                    case 0:
                        Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
                        intent.setType("text/*");
                        startActivityForResult(intent, READ_REQUEST_CODE);
                        break;

                    case 1:
                        if (Sys.canClick()) {
                            if (!outputDialog.isAdded()) {
                                outputDialog.show(getSupportFragmentManager(), "outputDialog");

                            }
                        }
                        break;
                    case 2:
                        if (Sys.fingerprintType == 0) {
                            QMUIDialogUtil.showMessagePositiveDialog(SetActivity.this, "关闭指纹", "是否要关闭指纹登录功能", new QMUIDialogAction.ActionListener() {
                                @Override
                                public void onClick(QMUIDialog dialog, int index) {
                                    SPUtil.put(getApplication(), "fingerprintType", 1);
                                    Sys.fingerprintType = (int) SPUtil.get(getApplicationContext(), "fingerprintType", 0);
                                    dialog.dismiss();
                                }
                            });
                        } else {
                            QMUIDialogUtil.showMessagePositiveDialog(SetActivity.this, "打开指纹", "是否要打开指纹登录功能", new QMUIDialogAction.ActionListener() {
                                @Override
                                public void onClick(QMUIDialog dialog, int index) {
                                    SPUtil.put(getApplication(), "fingerprintType", 0);
                                    Sys.fingerprintType = (int) SPUtil.get(getApplicationContext(), "fingerprintType", 0);
                                    dialog.dismiss();
                                }
                            });
                        }
                        break;
                    case 3:
                        if (Sys.canClick()&&!isIOUse) {
                            isIOUse =true;
                            executor.execute(outToHtml);
                        }
                        break;
                }
            }
        });
    }


    //申请读写权限
    public void requestPower() {
//判断是否已经赋予权限

        if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.WRITE_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {
            //如果应用之前请求过此权限但用户拒绝了请求，此方法将返回 true。
            if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                //这里可以写个对话框之类的项向用户解释为什么要申请权限，并在对话框的确认键后续再次申请权限.它在用户选择"不再询问"的情况下返回false

            } else {
                //申请权限，字符串数组内是一个或多个要申请的权限，1是申请权限结果的返回参数，在onRequestPermissionsResult可以得知申请结果
                ActivityCompat.requestPermissions(this,
                        new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,}, 1);
            }
        }
    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == READ_REQUEST_CODE) {
            try {
                textContent = data.getDataString();
            } catch (NullPointerException e) {
                Toast.makeText(this, "用户没有选择文件", Toast.LENGTH_LONG).show();
                return;
            }

            if (!inputDialog.isAdded()) {
                inputDialog.show(getSupportFragmentManager(), "inputDialog");
            }
        }
    }


    private String readFile(String key0) {

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        InputStream inputStream = null;


        try {
            inputStream =
                    getContentResolver().openInputStream(Uri.parse(textContent));

            byte[] buffer = new byte[1024];

            int len = 0;
            while ((len = inputStream.read(buffer)) != -1) {
                baos.write(buffer, 0, len);
            }
            byte[] b = baos.toByteArray();

            byte[] c = DESUtil.DESDecrypt(key0, b);
            String s = "";
            if (c != null) {
                s = new String(c);
            }
            return s;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }

            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return null;
    }


    private Runnable insertTask = new Runnable() {
        @Override
        public void run() {
            Gson gson = new Gson();
            List<UserBean> listBean = null;
            try {
                listBean = gson.fromJson(readJson, new TypeToken<List<UserBean>>() {
                }.getType());
            } catch (Exception e) {
                SetActivity.this.runOnUiThread(() -> {
                    tipDialog = new QMUITipDialog.Builder(SetActivity.this)
                            .setIconType(QMUITipDialog.Builder.ICON_TYPE_FAIL)
                            .setTipWord("密码错误或文件错误")
                            .create();
                    tipDialog.show();
                    dataBinding.listview.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            tipDialog.dismiss();
                        }
                    }, 1500);
                });
                return;
            }
            if (listBean != null && listBean.size() > 0) {
                UserDao userDao = AppDatabase.getInstance(SetActivity.this.getApplicationContext()).getUserDao();
                for (UserBean userBean : listBean) {
                    userBean.setId(0);
                    userDao.insertUserBean(userBean);
                }
                SetActivity.this.runOnUiThread(() -> {
                    tipDialog = new QMUITipDialog.Builder(SetActivity.this)
                            .setIconType(QMUITipDialog.Builder.ICON_TYPE_SUCCESS)
                            .setTipWord("导入成功")
                            .create();
                    tipDialog.show();
                    dataBinding.listview.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            tipDialog.dismiss();
                        }
                    }, 1500);
                });

            } else {
                SetActivity.this.runOnUiThread(() -> {
                    tipDialog = new QMUITipDialog.Builder(SetActivity.this)
                            .setIconType(QMUITipDialog.Builder.ICON_TYPE_FAIL)
                            .setTipWord("没有数据可导入")
                            .create();
                    tipDialog.show();
                    dataBinding.listview.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            tipDialog.dismiss();
                        }
                    }, 1500);
                });
            }

        }
    };

    private Runnable outToHtml =new Runnable() {
        @Override
        public void run() {
            list = AppDatabase.getInstance(SetActivity.this.getApplicationContext()).getUserDao().loadAllUserBean();
            if (list != null && list.size() > 0) {
                toHtml(list);
                SetActivity.this.runOnUiThread(() -> {
                    Toast.makeText(SetActivity.this, fileName, Toast.LENGTH_LONG).show();
                    tipDialog = new QMUITipDialog.Builder(SetActivity.this)
                            .setIconType(QMUITipDialog.Builder.ICON_TYPE_SUCCESS)
                            .setTipWord("导出成功")
                            .create();
                    tipDialog.show();
                    dataBinding.listview.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            tipDialog.dismiss();
                        }
                    }, 1500);
                });
            } else {
                SetActivity.this.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        tipDialog = new QMUITipDialog.Builder(SetActivity.this)
                                .setIconType(QMUITipDialog.Builder.ICON_TYPE_FAIL)
                                .setTipWord("没有数据可导出")
                                .create();
                        tipDialog.show();
                        dataBinding.listview.postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                tipDialog.dismiss();
                            }
                        }, 1500);
                    }
                });
            }
            isIOUse = false;
        }
    };

    private Runnable outputTask = new Runnable() {
        @Override
        public void run() {
            list = AppDatabase.getInstance(SetActivity.this.getApplicationContext()).getUserDao().loadAllUserBean();
            if (list != null && list.size() > 0) {
                Gson gson = new Gson();
                json = gson.toJson(list);
                writeByte = DESUtil.DESEncrypt(key, json);
                outPutFile();
                SetActivity.this.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(SetActivity.this, fileName, Toast.LENGTH_LONG).show();
                        tipDialog = new QMUITipDialog.Builder(SetActivity.this)
                                .setIconType(QMUITipDialog.Builder.ICON_TYPE_SUCCESS)
                                .setTipWord("导出成功")
                                .create();
                        tipDialog.show();
                        dataBinding.listview.postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                tipDialog.dismiss();
                            }
                        }, 1500);
                    }
                });
            } else {
                SetActivity.this.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        tipDialog = new QMUITipDialog.Builder(SetActivity.this)
                                .setIconType(QMUITipDialog.Builder.ICON_TYPE_FAIL)
                                .setTipWord("没有数据可导出")
                                .create();
                        tipDialog.show();
                        dataBinding.listview.postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                tipDialog.dismiss();
                            }
                        }, 1500);
                    }
                });
            }
            isIOUse = false;
        }
    };


    private String toHtmlString(String s){
        if (s!=null) {
            return s.replace("\n","<br/>");
        }
        return "";
    }
    private void toHtml(List<UserBean> data){
        StringBuffer stringBuffer=new StringBuffer();
        stringBuffer.append("<!DOCTYPE html>\n" +
                "<html>\n" +
                "\t<head>\n" +
                "\t\t<meta charset=\"utf-8\">\n" +
                "\t\t<title></title>\n" +
                "\t</head>\n" +
                "\t<body>\n" +
                "\t\t<table border=\"1\" cellspacing=\"0\" align=\"center\">");

        stringBuffer.append("<tr>\n");
        stringBuffer.append("<td>").append(toHtmlString("名称")).append("</td>").append("\n");
        stringBuffer.append("<td>").append(toHtmlString("账号")).append("</td>").append("\n");
        stringBuffer.append("<td>").append(toHtmlString("密码")).append("</td>").append("\n");
        stringBuffer.append("<td>").append(toHtmlString("内容")).append("</td>").append("\n");
        stringBuffer.append("<td>").append(toHtmlString("secretKey")).append("</td>").append("\n");
        stringBuffer.append("</tr>\n");
        for (int i = 0; i < data.size(); i++) {
            UserBean userBean = data.get(i);
            stringBuffer.append("<tr>\n");
            stringBuffer.append("<td>").append(toHtmlString(userBean.getName())).append("</td>").append("\n");
            stringBuffer.append("<td>").append(toHtmlString(userBean.getUsername())).append("</td>").append("\n");
            stringBuffer.append("<td>").append(toHtmlString(userBean.getPassword())).append("</td>").append("\n");
            stringBuffer.append("<td>").append(toHtmlString(userBean.getContent())).append("</td>").append("\n");
            stringBuffer.append("<td>").append(toHtmlString(userBean.getSecretKey())).append("</td>").append("\n");
            stringBuffer.append("</tr>\n");
        }

        stringBuffer.append("\t</table>\n" +
                "\t</body>\n" +
                "</html>");
        byte[] writeByte=stringBuffer.toString().getBytes();

        long l = System.currentTimeMillis();
        String date = TimeUtil.stampToDate(l + "");
        fileName = "psd_" + date + ".html";

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {

            Uri uri = insertFileIntoMediaStore(this, fileName, "text/*", "Download/passwordManager");
            saveFile(this, uri,writeByte);
        } else {
            saveFile2(fileName,writeByte);
        }
    }

    private void outPutFile() {
        long l = System.currentTimeMillis();
        String date = TimeUtil.stampToDate(l + "");
        fileName = "psd_" + date + ".txt";

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {

            Uri uri = insertFileIntoMediaStore(this, fileName, "text/*", "Download/passwordManager");
            saveFile(this, uri,writeByte);
        } else {
            saveFile2(fileName,writeByte);
        }
    }


    /**
     * android 10以上
     *
     * @param context
     * @param fileName
     * @param fileType
     * @param relativePath
     * @return
     */
    //relativePath 包含某个媒体下的子路径   这里的fileName指文件名，不包含路径
    private static Uri insertFileIntoMediaStore(Context context, String fileName, String fileType, String relativePath) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
            return null;
        }
        ContentResolver resolver = context.getContentResolver();
        //设置文件参数到ContentValues中
        ContentValues values = new ContentValues();
        //设置文件名
        values.put(MediaStore.Downloads.DISPLAY_NAME, fileName);

        //设置文件类型
        values.put(MediaStore.Downloads.MIME_TYPE, fileType);

        //注意RELATIVE_PATH需要targetVersion=29
        //故该方法只可在Android10的手机上执行
        values.put(MediaStore.Downloads.RELATIVE_PATH, relativePath);
        //EXTERNAL_CONTENT_URI代表外部存储器
        Uri external = MediaStore.Downloads.EXTERNAL_CONTENT_URI;
        //insertUri表示文件保存的uri路径
        Uri insertUri = resolver.insert(external, values);
        return insertUri;
    }


    private void saveFile2(String fileName, byte[] writeByte) {
        String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath();
        path = path + "/passwordManager/";
        File file1 = new File(path);
        if (!file1.exists()) {
            file1.mkdirs();
        }
        File file = new File(path, fileName);
        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream(file);
            fileOutputStream.write(writeByte);
            fileOutputStream.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fileOutputStream != null) {
                    fileOutputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }


    private void saveFile(Context context, Uri insertUri,byte[] writeByte) {
        if (insertUri == null) {
            return;
        }
        ContentResolver resolver = context.getContentResolver();
        String mFilePath = insertUri.toString();

        OutputStream os = null;
        try {
            os = resolver.openOutputStream(insertUri);
            if (os == null) {
                return;
            }
            os.write(writeByte);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (os != null) {
                    os.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


}